home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Memphis Amiga Group
/
MAG DOS 2.0 Utilities Disk 06 (1992-04)(Memphis Amiga Group).zip
/
MAG DOS 2.0 Utilities Disk 06 (1992-04)(Memphis Amiga Group).adf
/
TG
/
TG_Sources.lzh
/
TG_Eyes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-06
|
20KB
|
628 lines
/* ==================================================================== */
/* */
/* Programname : TG Eyes.c (1.0b) */
/* Author & Copyright : Thomas Geib, 6750 Kaiserslautern */
/* Date : 31 July 1991 */
/* */
/* Please refer to the "TG Eyes.doc" file for terms of copying and */
/* usage of this program. */
/* This program is "AS IS" : no responsibility for any damage of */
/* soft- / hardware is given. */
/* */
/* I have included this source-code for programmers, who want to find */
/* out how to do certain stuff like reading parameters (from WB and */
/* CLI), how to do graphics with tmp-rastports, rastports and clipping */
/* into the workbenchscreen. I have learned from other people's source */
/* code as well. */
/* */
/* If you want to use this source-code for your own version of */
/* "TG Eyes", you need to contact me !!! ( see TG Eyes.doc file ) */
/* */
/* For compilation (Aztec 5.0) + linking: see makefile */
/* */
/* */
/* Have fun ... */
/* Tom */
/* */
/* ==================================================================== */
#define DEFAULT_WIDTH 196
#define DEFAULT_HEIGHT 72
#define DEFAULT_X 60
#define DEFAULT_Y 18
#define DEFAULT_MAXWIDTH 300
#define DEFAULT_MAXHEIGHT 110
#define DEFAULT_DELAY 5
#define DEFAULT_PRIORITY -10
#define TWO_PI 6.28318531
#define PROP_LEFT_EYE_X 550 /* according to width and height */
#define PROP_RIGHT_EYE_X 1500
#define PROP_EYE_Y 1000
#define PROP_PUPIL_X 250 /* distance middle of pupil to center of eye */
#define PROP_PUPIL_Y 500
#define PROP_INV_RIM_X 350
#define PROP_INV_RIM_Y 700
#define PROP_INNER_RIM_X 400 /* distance inner rim to " " " " " */
#define PROP_INNER_RIM_Y 800
#define PROP_OUTER_RIM_X 450
#define PROP_OUTER_RIM_Y 900
#define EYE_COLOR 0
#define RIM_COLOR 1
#define LEFT 0
#define RIGHT 1
#define ERR_NONE 0
#define ERR_BITPLANE 1
#define ERR_GFX 2
#define ERR_INTUI 3
#define ERR_WIN 4
#define ERR_PLANE_0 5
#define ERR_PLANE_1 6
#define ERR_LITTLE_PLANE_0 7
#define ERR_LITTLE_PLANE_1 8
#include <exec/types.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <intuition/intuition.h>
#include <math.h>
#include <workbench/startup.h>
#include <workbench/icon.h>
#include <workbench/workbench.h>
struct NewWindow nw =
{
DEFAULT_X,DEFAULT_Y,DEFAULT_WIDTH,DEFAULT_HEIGHT,0,1,
CLOSEWINDOW | DISKREMOVED | DISKINSERTED | REFRESHWINDOW,
WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SIMPLE_REFRESH,
NULL,NULL,(UBYTE *)"TG Eyes",NULL,NULL,
100, 33, DEFAULT_MAXWIDTH, DEFAULT_MAXHEIGHT,
WBENCHSCREEN
};
struct IntuiText MenuText_Settings[13] =
{
{ 0,1,JAM1,10, 5,NULL,(UBYTE *)"How to set TG Eyes parameter: ",(struct IntuiText *)&MenuText_Settings[1] },
{ 0,1,JAM1,10, 20,NULL,(UBYTE *)"PARAMETER CLI WORKBENCH-INFO",(struct IntuiText *)&MenuText_Settings[2] },
{ 0,1,JAM1,10, 30,NULL,(UBYTE *)"--------- --- --------------",(struct IntuiText *)&MenuText_Settings[3] },
{ 0,1,JAM1,10, 40,NULL,(UBYTE *)"Left window edge X=nr LEFTEDGE=nr ",(struct IntuiText *)&MenuText_Settings[4] },
{ 0,1,JAM1,10, 50,NULL,(UBYTE *)"Top window edge Y=nr TOPEDGE=nr ",(struct IntuiText *)&MenuText_Settings[5] },
{ 0,1,JAM1,10, 60,NULL,(UBYTE *)"Window width W=nr WIDTH=nr ",(struct IntuiText *)&MenuText_Settings[6] },
{ 0,1,JAM1,10, 70,NULL,(UBYTE *)"Window height H=nr HEIGHT=nr ",(struct IntuiText *)&MenuText_Settings[7] },
{ 0,1,JAM1,10, 80,NULL,(UBYTE *)"Window max.width MW=nr MAXWIDTH=nr ",(struct IntuiText *)&MenuText_Settings[8] },
{ 0,1,JAM1,10, 90,NULL,(UBYTE *)"Window max.height MH=nr MAXHEIGHT=nr ",(struct IntuiText *)&MenuText_Settings[9] },
{ 0,1,JAM1,10, 100,NULL,(UBYTE *)"Process delay D=nr DELAY=nr ",(struct IntuiText *)&MenuText_Settings[10]},
{ 0,1,JAM1,10, 110,NULL,(UBYTE *)"Task priority P=nr PRIORITY=nr ",(struct IntuiText *)&MenuText_Settings[11]},
{ 0,1,JAM1,10, 125,NULL,(UBYTE *)"Sizing gadget hidden in lower right edge. ",(struct IntuiText *)&MenuText_Settings[12]},
{ 0,1,JAM1,10, 135,NULL,(UBYTE *)"Please refer to TG Eyes.doc for more info.",NULL }
};
struct MenuItem Item_Settings =
{
NULL,0,0,362,145,ITEMTEXT | ITEMENABLED | HIGHNONE,0L,
&MenuText_Settings,NULL,0,NULL,NULL
};
struct Menu MySettingsMenu =
{ NULL,70,0,88,10,MENUENABLED,(char *)"Parameters",&Item_Settings };
struct IntuiText MenuText_Copyright[8] =
{
{ 0,1,JAM1,10, 5,NULL,(UBYTE *)" TG Eyes ",(struct IntuiText *)&MenuText_Copyright[1] },
{ 0,1,JAM1,10,15,NULL,(UBYTE *)" (c)1991 Thomas Geib ",(struct IntuiText *)&MenuText_Copyright[2] },
{ 0,1,JAM1,10,30,NULL,(UBYTE *)"This program is NOT PUBLIC DOMAIN,but ",(struct IntuiText *)&MenuText_Copyright[3] },
{ 0,1,JAM1,10,40,NULL,(UBYTE *)"it may be copied under the terms given",(struct IntuiText *)&MenuText_Copyright[4] },
{ 0,1,JAM1,10,50,NULL,(UBYTE *)"in the TG Eyes.doc file ! ",(struct IntuiText *)&MenuText_Copyright[5] },
{ 0,1,JAM1,10,65,NULL,(UBYTE *)"No responsibility for any damage of ",(struct IntuiText *)&MenuText_Copyright[6] },
{ 0,1,JAM1,10,75,NULL,(UBYTE *)"software/hardware on the use of this ",(struct IntuiText *)&MenuText_Copyright[7] },
{ 0,1,JAM1,10,85,NULL,(UBYTE *)"program given ! ",NULL }
};
struct MenuItem Item_Copyright =
{
NULL,0,0,326,95,ITEMTEXT | ITEMENABLED | HIGHNONE,0L,
&MenuText_Copyright,NULL,0,NULL,NULL
};
struct Menu MyMenu =
{ &MySettingsMenu,10,0,40,10,MENUENABLED,(UBYTE *)"Info",&Item_Copyright };
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct IconBase *IconBase;
struct Window *win; /* window variables */
struct IntuiMessage *message;
struct TmpRas tmp; /* temporary rastport vars */
APTR tmp_rp_plane;
WORD areabuffer[200];
struct AreaInfo areaInfo;
struct RastPort rp_struct; /* rastport for drawing */
struct RastPort *rp;
struct BitMap bitMap;
struct RastPort little_rp; /* rastport for drawing pupil. */
struct BitMap little_bm; /* shares tmp_rp with rp for filling */
int little_width,little_height;
struct Task *mytask;
int height_nodrag, /* some help variables -> no stupid */
eye_minus_pupil_y, /* calculations on constants ! */
eye_minus_pupil_x[2],
width_noborders,
MouseX,MouseY,NewMouseX,NewMouseY,
eye_width,eye_height,
pupil_radius_x,pupil_radius_y,
pupil_diameter_x,pupil_diameter_y,
pupil_x[2],pupil_y[2],
eye_x [2],eye_y,
eye_inner_rim_x,eye_inner_rim_y, /* radius' for drawing rims */
eye_outer_rim_x,eye_outer_rim_y,
eye_inv_rim_x_i,eye_inv_rim_y_i; /* same as below, but int */
float eye_inv_rim_x,eye_inv_rim_y,SCALE_X;
int delay = DEFAULT_DELAY;
priority = DEFAULT_PRIORITY;
old_priority;
DRAGBAR = 11; /* we'll look at system gadgets later for real height */
int OpenAll()
{
struct Gadget *gadget;
/* ===================== OPEN LIBRARIES =========================== */
if (! (GfxBase = OpenLibrary ("graphics.library",0L)) )
return (ERR_GFX);
if (! (IntuitionBase = OpenLibrary ("intuition.library",0L)) )
return (ERR_INTUI);
if (! (win = OpenWindow (&nw)) )
return ( ERR_WIN );
/* =============== CREATE RASTPORT FOR DRAWING ==================== */
InitBitMap ( &bitMap ,2,win->MaxWidth,win->MaxHeight );
if (! (bitMap.Planes[0] = AllocRaster (win->MaxWidth,win->MaxHeight)))
return ( ERR_PLANE_0 );
if (! (bitMap.Planes[1] = AllocRaster (win->MaxWidth,win->MaxHeight)))
return ( ERR_PLANE_1 );
InitRastPort ( &rp_struct );
rp_struct.BitMap = &bitMap;
rp = &rp_struct;
/* ======= CREATE TEMPORARY RASTPORT FOR FILL OPERATIONS =========== */
if (! (tmp_rp_plane = AllocRaster (win->MaxWidth,win->MaxHeight)) ) return (ERR_BITPLANE);
InitArea ( &areaInfo,areabuffer,80);
rp->AreaInfo = &areaInfo;
InitTmpRas (&tmp,tmp_rp_plane,RASSIZE (win->MaxWidth,win->MaxHeight));
rp->TmpRas = &tmp;
/* ====== CREATE LITTLE RASTPORT FOR DRAWING SOLID ELLIPSE ========= */
little_width = (win->MaxWidth * (PROP_INV_RIM_X - PROP_PUPIL_X)) >> 10;
little_height = (win->MaxHeight * (PROP_INV_RIM_Y - PROP_PUPIL_Y)) >> 10;
little_width++; little_height++;
InitBitMap (&little_bm,2,little_width,little_height);
if (! (little_bm.Planes[0] = AllocRaster (little_width,little_height)))
return ( ERR_LITTLE_PLANE_0 );
if (! (little_bm.Planes[1] = AllocRaster (little_width,little_height)))
return ( ERR_LITTLE_PLANE_1 );
InitRastPort ( &little_rp );
little_rp.BitMap = &little_bm;
little_rp.TmpRas = &tmp;
little_rp.AreaInfo = &areaInfo;
SetMenuStrip (win,&MyMenu);
(win->WScreen->ViewPort.Modes & LACE) ? (SCALE_X=1.4):(SCALE_X=0.7);
mytask = FindTask (NULL);
if (mytask) old_priority = SetTaskPri ( mytask,priority );
/* search system gadget list for height of dragbar */
gadget = win->FirstGadget;
while (gadget)
{
if ( gadget->GadgetType == (SYSGADGET | WDRAGGING) )
{
DRAGBAR = gadget->Height+1;
gadget = NULL ; /* quit */
}
else gadget = gadget->NextGadget;
}
return ( ERR_NONE );
}
void CloseAll ( int ErrCode )
{
switch (ErrCode)
{
case ERR_NONE : SetTaskPri (mytask,old_priority);
ClearMenuStrip(win,&MyMenu);
FreeRaster (little_bm.Planes[1],little_width,little_height);
case ERR_LITTLE_PLANE_1 : FreeRaster (little_bm.Planes[0],little_width,little_height);
case ERR_LITTLE_PLANE_0 : FreeRaster (tmp_rp_plane,win->MaxWidth,win->MaxHeight);
case ERR_BITPLANE : FreeRaster (bitMap.Planes[1],win->MaxWidth,
win->MaxHeight);
case ERR_PLANE_1 : FreeRaster (bitMap.Planes[0],win->MaxWidth,
win->MaxHeight);
case ERR_PLANE_0 : CloseWindow (win);
case ERR_WIN : CloseLibrary (IntuitionBase);
case ERR_INTUI : CloseLibrary (GfxBase);
}
}
void DrawRims()
{
int i;
SetAPen (rp,0);
RectFill (rp,2,DRAGBAR,win->Width -3,win->Height -1);
SetAPen (rp,RIM_COLOR);
for (i=LEFT;i<=RIGHT;i++)
{
AreaEllipse (rp,eye_x [i],eye_y,eye_outer_rim_x,eye_outer_rim_y);
AreaEnd(rp);
}
SetAPen (rp,EYE_COLOR);
for (i=LEFT;i<=RIGHT;i++)
{
AreaEllipse (rp,eye_x [i],eye_y,eye_inner_rim_x,eye_inner_rim_y);
AreaEnd(rp);
}
SetAPen (&little_rp,0);
RectFill (&little_rp,0,0,little_width-1,little_height-1);
SetAPen (&little_rp,3);
AreaEllipse ( &little_rp,pupil_radius_x,pupil_radius_y,
pupil_radius_x,pupil_radius_y );
AreaEnd (&little_rp);
SetWrMsk ( win->RPort,0xFF );
ClipBlit ( rp,2,DRAGBAR,win->RPort,2,DRAGBAR,
width_noborders,height_nodrag,0xC0 );
SetWrMsk ( win->RPort,0xFE );
}
void DrawFace()
{
eye_height = (win->Height - DRAGBAR) >> 1;
eye_width = (win->Width) >> 1;
/* ======= coordinates of eyes =================== */
eye_x [LEFT] = (PROP_LEFT_EYE_X * eye_width) >> 10;
eye_x [RIGHT] = (PROP_RIGHT_EYE_X * eye_width) >> 10;
eye_y = ((PROP_EYE_Y * eye_height) >> 10) + DRAGBAR;
/* ======= radius for drawing eye-rim ellipses ======= */
eye_inner_rim_x = (PROP_INNER_RIM_X * eye_width) >> 10;
eye_inner_rim_y = (PROP_INNER_RIM_Y * eye_height) >> 10;
eye_outer_rim_x = (PROP_OUTER_RIM_X * eye_width) >> 10;
eye_outer_rim_y = (PROP_OUTER_RIM_Y * eye_height) >> 10;
eye_inv_rim_x = (float)(PROP_PUPIL_X * eye_width) / 1024.0;
eye_inv_rim_y = (float)(PROP_PUPIL_Y * eye_height) / 1024.0;
eye_inv_rim_x_i = (int)(eye_inv_rim_x+0.5);
eye_inv_rim_y_i = (int)(eye_inv_rim_y+0.5);
/* ======= radius and diameter for drawing pupil ellipse ========== */
pupil_radius_x = abs(((PROP_INV_RIM_X - PROP_PUPIL_X) * eye_width) >> 10);
pupil_radius_y = abs(((PROP_INV_RIM_Y - PROP_PUPIL_Y) * eye_height) >> 10);
pupil_diameter_x = (pupil_radius_x <<1) + 1;
pupil_diameter_y = (pupil_radius_y <<1) + 1;
pupil_x [LEFT] = 0;
eye_minus_pupil_y = eye_y - pupil_radius_y;
eye_minus_pupil_x[LEFT] = eye_x [LEFT] - pupil_radius_x;
eye_minus_pupil_x[RIGHT] = eye_x [RIGHT] - pupil_radius_x;
height_nodrag = win->Height - DRAGBAR -1; /* for clip()ing */
width_noborders = win->Width - 4;
MouseX = MouseY = -1;
DrawRims();
}
void DrawPupils ()
{
float alpha;
int dx_i,dy_i,i;
MouseX = NewMouseX;
MouseY = NewMouseY;
if (pupil_x [LEFT]) /* clear old pupils graphic */
{
ClipBlit ( &little_rp,0,0,rp,pupil_x [LEFT],pupil_y [LEFT],
pupil_diameter_x,pupil_diameter_y,0x60);
ClipBlit ( &little_rp,0,0,rp,pupil_x [RIGHT],pupil_y [RIGHT],
pupil_diameter_x,pupil_diameter_y,0x60);
}
dy_i = MouseY - eye_y;
for (i=LEFT;i<=RIGHT;i++)
{
dx_i = MouseX - eye_x [i];
alpha = atan2 ( (float)dy_i,(float)dx_i * SCALE_X );
pupil_x [i] = (int) ( cos(alpha) * eye_inv_rim_x );
pupil_y [i] = (int) ( sin(alpha) * eye_inv_rim_y );
if ( ( abs(dx_i) <= abs(pupil_x [i]) ) &&
( abs(dy_i) <= abs(pupil_y [i]) ) )
{
pupil_x [i] = MouseX - pupil_radius_x;
pupil_y [i] = MouseY - pupil_radius_y;
}
else
{
pupil_x [i] = pupil_x [i] + eye_minus_pupil_x [i]; /* does not work with += */
pupil_y [i] = pupil_y [i] + eye_minus_pupil_y; /* and I have no idea,why */
}
ClipBlit ( &little_rp,0,0,rp,pupil_x [i],pupil_y [i],
pupil_diameter_x,pupil_diameter_y,0x60);
}
ClipBlit ( rp,2,DRAGBAR,win->RPort,2,DRAGBAR,
width_noborders,height_nodrag,0xC0 );
}
void DrawSpecial (float alpha, float beta )
{
int i;
if (pupil_x [LEFT]) /* clear old pupils graphic */
{
ClipBlit ( &little_rp,0,0,rp,pupil_x [LEFT],pupil_y [LEFT],
pupil_diameter_x,pupil_diameter_y,0x60);
ClipBlit ( &little_rp,0,0,rp,pupil_x [RIGHT],pupil_y [RIGHT],
pupil_diameter_x,pupil_diameter_y,0x60);
}
for (i=LEFT;i<=RIGHT;i++)
{
pupil_x [i] = (int) ( cos(alpha) * eye_inv_rim_x )
+ eye_minus_pupil_x [i];
pupil_y [i] = (int) ( sin(alpha) * eye_inv_rim_y )
+ eye_minus_pupil_y;
ClipBlit ( &little_rp,0,0,rp,pupil_x [i],pupil_y [i],
pupil_diameter_x,pupil_diameter_y,0x60);
alpha = beta;
}
ClipBlit ( rp,2,DRAGBAR,win->RPort,2,DRAGBAR,
width_noborders,height_nodrag,0xC0 );
}
void Roll_Eyes ( int inserted )
{
float alpha,beta,dx,dy,gamma;
dy = (float)(win->MouseY - eye_y);
dx = (float)(win->MouseX - eye_x[0]) * SCALE_X;
alpha = atan2 ( dy,dx );
dx = (float)(win->MouseX - eye_x[1]) * SCALE_X;
beta = atan2 ( dy,dx );
if (inserted) Delay ( 50 );
gamma = 0.0;
while (gamma < TWO_PI)
{
DrawSpecial (alpha,beta);
gamma += 0.15;
alpha += 0.15;
beta -= 0.15;
}
DrawPupils();
}
void HandleIDCMP ()
{
USHORT class;
for (;;)
{
while ( message = (struct IntuiMessage *) GetMsg (win->UserPort) )
{
class = message->Class;
ReplyMsg ((struct Message *)message);
switch (class)
{
case CLOSEWINDOW : return();
case REFRESHWINDOW : DrawFace(); break;
case DISKREMOVED : Roll_Eyes(0); break;
case DISKINSERTED : Roll_Eyes(1); break;
}
}
NewMouseX = win->MouseX;
NewMouseY = win->MouseY;
if ( (NewMouseX != MouseX) || (NewMouseY != MouseY) )
DrawPupils ();
Delay (delay);
}
}
int compare ( char *str_ptr_1, char *str_ptr_2, int length )
{
APTR ptr;
if (! (strncmp ( str_ptr_1,str_ptr_2,length )) )
{
if ((strlen (str_ptr_2)) > length)
{
ptr = (APTR) ((int)str_ptr_2 + (int)length);
return ( atoi (ptr));
}
}
return ( -1 );
}
void GetParameters ( int count, char *arg_ptr[],
struct WBStartup *arg_wb_ptr )
{
int i,x;
struct WB_Arg *wb_args;
struct DiskObject *disk_obj;
char **toolarray;
char *s;
if (count)
{
for (i=1;i<count;i++)
{
if ( (x = compare ("X=",arg_ptr[i],2)) != -1 )
nw.LeftEdge = x;
else
if ( (x = compare ("Y=",arg_ptr[i],2)) != -1 )
nw.TopEdge = x;
else
if ( (x = compare ("W=",arg_ptr[i],2)) != -1 )
nw.Width = x;
else
if ( (x = compare ("H=",arg_ptr[i],2)) != -1 )
nw.Height = x;
else
if ( (x = compare ("MW=",arg_ptr[i],3)) != -1 )
nw.MaxWidth = x;
else
if ( (x = compare ("MH=",arg_ptr[i],3)) != -1 )
nw.MaxHeight = x;
if ( (x = compare ("D=",arg_ptr[i],2)) != -1 )
delay = x;
else
if ( (x = compare ("P=",arg_ptr[i],2)) != -1 )
priority = x;
}
}
else
{ /* started from workbench */
if ( IconBase = OpenLibrary ("icon.library",0L) )
{
wb_args = (struct WBArg *)arg_wb_ptr->sm_ArgList;
if (*wb_args->wa_Name)
{
if (disk_obj = GetDiskObject (wb_args->wa_Name))
{
toolarray = (char **) disk_obj->do_ToolTypes;
if (s=(char *)FindToolType(toolarray,"LEFTEDGE"))
nw.LeftEdge = atoi (s);
if (s=(char *)FindToolType(toolarray,"TOPEDGE"))
nw.TopEdge = atoi (s);
if (s=(char *)FindToolType(toolarray,"WIDTH"))
nw.Width = atoi (s);
if (s=(char *)FindToolType(toolarray,"HEIGHT"))
nw.Height = atoi (s);
if (s=(char *)FindToolType(toolarray,"MAXWIDTH"))
nw.MaxWidth = atoi (s);
if (s=(char *)FindToolType(toolarray,"MAXHEIGHT"))
nw.MaxHeight = atoi (s);
if (s=(char *)FindToolType(toolarray,"DELAY"))
delay = atoi(s);
if (s=(char *)FindToolType(toolarray,"PRIORITY"))
priority = atoi (s);
FreeDiskObject ( disk_obj );
}
}
CloseLibrary (IconBase);
}
}
/* now check parameters */
if ( (delay < 0) || (delay > 500) ) delay = DEFAULT_DELAY;
if ( (priority < 128) || (priority > 127) ) priority = DEFAULT_PRIORITY;
if (nw.Width < nw.MinWidth) nw.Width = nw.MinWidth;
if (nw.Height < nw.MinHeight) nw.Height = nw.MinHeight;
if (nw.MaxWidth < nw.Width) nw.MaxWidth = nw.Width;
if (nw.MaxHeight < nw.MaxHeight) nw.MaxHeight = nw.Height;
if (nw.LeftEdge < 0) nw.LeftEdge = 0;
if (nw.TopEdge < 0) nw.TopEdge = 0;
}
int main ( int argc, char *argv[] )
{
int ErrCode;
GetParameters (argc,argv,argv);
if ( ( ErrCode = OpenAll() ) == ERR_NONE )
{
DrawFace ();
NewMouseX = win->MouseX;
NewMouseY = win->MouseY;
DrawPupils ();
HandleIDCMP ();
}
CloseAll ( ErrCode );
return (0);
}